#include "NameSvrClient.h"
#include "NameSvrCommon.h"
#include "ProtoHelper.h"
#include "NameSvrClientProtoHelper.h"


LoggerPtr NameSvrClient::_logger = Logger::getLogger("NameSvrClient");

int NameSvrClient::init(const char * svr_ip, const unsigned svr_port, const int conn_pool_size, const int conn_timeout, \
                                const int send_timeout, const int recv_timeout, const int max_response_size) {
	if (NULL == svr_ip || conn_pool_size < 1) {
		LOG4CXX_ERROR(_logger, "init error, invalid args");
		return -1;
	}
	_svr_ip = svr_ip;
	_svr_port = svr_port;
	_conn_pool_size = conn_pool_size;
	_conn_timeout = conn_timeout;
	_send_timeout = send_timeout;
	_recv_timeout = recv_timeout;
	_max_response_size = max_response_size;
	int ret = _pool.init(svr_ip, svr_port, conn_timeout, conn_pool_size);
        if (ret < 0) {
                LOG4CXX_ERROR(_logger, "conn pool init error, ret:" << ret << ", svr_ip:" << svr_ip << ", svr_port:" << \
                                svr_port << ", conn_timeout:" << conn_timeout << ", conn_pool_size:" << conn_pool_size);
                return -2;
        }
        LOG4CXX_INFO(_logger, "NameSvrClient init ok, svr_ip:" << svr_ip << ", svr_port:" << svr_port << ", conn_timeout:" << \
                        conn_timeout << ", conn_pool_size:" << ", send_timeout:" << send_timeout << ", recv_timeout:" << \
                        recv_timeout);
        return 1;
}

int NameSvrClient::create_file(const char * file_path, int32_t mds_id, int32_t dir_id, int64_t file_id) {
	if (NULL == file_path || mds_id < 0 || dir_id < 0 || file_id < 0) {
		LOG4CXX_ERROR(_logger, "create file, invalid args");
		return NS_ERR_CLIENT_DETECTED_INVALID_ARGS;
	}
	SocketConnPtr cp;
        int ret = _pool.get(cp);
        if (ret < 0) {
                LOG4CXX_ERROR(_logger, "create_file, could not get connection from pool, file:" << file_path << ", mds_id:" << \
					mds_id << ", dir_id:" << dir_id << ", file_id:" << file_id);
                return NS_ERR_CLIENT_TO_SVR_NETWORK_ERR;
        }
        string request = ns_build_request_create_file(file_path, mds_id, dir_id, file_id);
        string response;
        ret = send_and_recv_cmd(cp, _send_timeout, _recv_timeout, request.c_str(), request.size(), _max_response_size, response);
        if (ret < 0) {
                LOG4CXX_ERROR(_logger, "create_file, send and recv cmd error, ret:" << ret << ", file_path:" << file_path);
                return NS_ERR_CLIENT_TO_SVR_NETWORK_ERR;
        }
	int result;
	ret = ns_parse_response_create_file(response.c_str(), result); 
	if (ret < 0) return NS_ERR_INVALID_RESPONSE;
	return result;
}

int NameSvrClient::delete_file(const char * file_path) {
	if (NULL == file_path) {
		LOG4CXX_ERROR(_logger, "delete file error, invalid args");
		return NS_ERR_CLIENT_DETECTED_INVALID_ARGS;
	}
	SocketConnPtr cp;
        int ret = _pool.get(cp);
        if (ret < 0) {
                LOG4CXX_ERROR(_logger, "delete_file, could not get connection from pool:" << file_path);
                return NS_ERR_CLIENT_TO_SVR_NETWORK_ERR;
        }
        string request = ns_build_request_delete_file(file_path);
        string response;
        ret = send_and_recv_cmd(cp, _send_timeout, _recv_timeout, request.c_str(), request.size(), _max_response_size, response);
        if (ret < 0) {
                LOG4CXX_ERROR(_logger, "delete_file, send and recv cmd error, ret:" << ret << ", file_path:" << file_path);
                return NS_ERR_CLIENT_TO_SVR_NETWORK_ERR;
        }
	int result;
	ret = ns_parse_response_delete_file(response.c_str(), result);
	if (ret < 0) return NS_ERR_INVALID_RESPONSE;
	return result;
}

int NameSvrClient::create_dir(const char * dir_path) {
	if (NULL == dir_path) {
		LOG4CXX_ERROR(_logger, "create dir error, invalid args");
		return NS_ERR_CLIENT_DETECTED_INVALID_ARGS;
	}
	SocketConnPtr cp;
        int ret = _pool.get(cp);
        if (ret < 0) {
                LOG4CXX_ERROR(_logger, "create_dir, could not get connection from pool:" << dir_path);
                return NS_ERR_CLIENT_TO_SVR_NETWORK_ERR;
        }
        string request = ns_build_request_create_dir(dir_path);
        string response;
        ret = send_and_recv_cmd(cp, _send_timeout, _recv_timeout, request.c_str(), request.size(), _max_response_size, response);
        if (ret < 0) {
                LOG4CXX_ERROR(_logger, "create_dir, send and recv cmd error, ret:" << ret << ", dir_path:" << dir_path);
                return NS_ERR_CLIENT_TO_SVR_NETWORK_ERR;
        }
	int result;
	ret = ns_parse_response_create_dir(response.c_str(), result);
	if (ret < 0) return NS_ERR_INVALID_RESPONSE;
	return result;
}

int NameSvrClient::delete_dir(const char * dir_path) {
	if (NULL == dir_path) {
		LOG4CXX_ERROR(_logger, "delete dir error,  invalid args");
		return NS_ERR_CLIENT_DETECTED_INVALID_ARGS;
	}
	SocketConnPtr cp;
        int ret = _pool.get(cp);
        if (ret < 0) {
                LOG4CXX_ERROR(_logger, "delete_dir, could not get connection from pool, dir:" << dir_path);
                return NS_ERR_CLIENT_TO_SVR_NETWORK_ERR;
        }
        string request = ns_build_request_delete_dir(dir_path);
        string response;
        ret = send_and_recv_cmd(cp, _send_timeout, _recv_timeout, request.c_str(), request.size(), _max_response_size, response);
        if (ret < 0) {
                LOG4CXX_ERROR(_logger, "delete_dir, send and recv cmd error, ret:" << ret << ", dir_path:" << dir_path);
                return NS_ERR_CLIENT_TO_SVR_NETWORK_ERR;
        }
	int result;
	ret = ns_parse_response_delete_dir(response.c_str(), result);
	if (ret < 0) return NS_ERR_INVALID_RESPONSE;
	return result;
}

int NameSvrClient::get_file_metadata_info(const char * file_path, FILE_METADATA_INFO & info) {
	if (NULL == file_path) {
		LOG4CXX_ERROR(_logger, __FUNCTION__ << " error, invalid args");
		return NS_ERR_CLIENT_DETECTED_INVALID_ARGS;
	}
	SocketConnPtr cp;
        int ret = _pool.get(cp);
        if (ret < 0) {
                LOG4CXX_ERROR(_logger, __FUNCTION__ << " error, could not get connection from pool, file:" << file_path);
                return NS_ERR_CLIENT_TO_SVR_NETWORK_ERR;
        }
        string request = ns_build_request_get_file_metadata_info(file_path);
        string response;
        ret = send_and_recv_cmd(cp, _send_timeout, _recv_timeout, request.c_str(), request.size(), _max_response_size, response);
        if (ret < 0) {
                LOG4CXX_ERROR(_logger, "get_file_metadata_svr_info, send and recv cmd error, ret:" << ret << ", file_path:" << \
				file_path);
                return NS_ERR_CLIENT_TO_SVR_NETWORK_ERR;
        }
	int result;
	ret = ns_parse_response_get_file_metadata_info(response.c_str(), result, info);
	if (ret < 0) return NS_ERR_INVALID_RESPONSE;
	return result;
}

int NameSvrClient::alloc_mds_4_new_file(int32_t & mds_id) {
	SocketConnPtr cp;
        int ret = _pool.get(cp);
        if (ret < 0) {
                LOG4CXX_ERROR(_logger, __FUNCTION__ << ", could not get connection from pool");
                return NS_ERR_CLIENT_TO_SVR_NETWORK_ERR;
        }
        string request = ns_build_request_alloc_mds_4_new_file();
        string response;
        ret = send_and_recv_cmd(cp, _send_timeout, _recv_timeout, request.c_str(), request.size(), _max_response_size, response);
        if (ret < 0) {
                LOG4CXX_ERROR(_logger, __FUNCTION__ << ", send and recv cmd error, ret:" << ret);
                return NS_ERR_CLIENT_TO_SVR_NETWORK_ERR;
        }
	int result;
	ret = ns_parse_response_alloc_mds_4_new_file(response.c_str(), result, mds_id);
	if (ret < 0) return NS_ERR_INVALID_RESPONSE;
	return result;

}

int NameSvrClient::query_is_file_exist(const char * file_path, int32_t & exist_flag) {
	SocketConnPtr cp;
        int ret = _pool.get(cp);
        if (ret < 0) {
                LOG4CXX_ERROR(_logger, __FUNCTION__ << ", could not get connection from pool");
                return NS_ERR_CLIENT_TO_SVR_NETWORK_ERR;
        }
        string request = ns_build_request_query_is_file_exist(file_path);
        string response;
        ret = send_and_recv_cmd(cp, _send_timeout, _recv_timeout, request.c_str(), request.size(), _max_response_size, response);
        if (ret < 0) {
                LOG4CXX_ERROR(_logger, __FUNCTION__ << ", send and recv cmd error, ret:" << ret);
                return NS_ERR_CLIENT_TO_SVR_NETWORK_ERR;
        }
	int result;
	ret = ns_parse_response_query_is_file_exist(response.c_str(), result, exist_flag);
	if (ret < 0) return NS_ERR_INVALID_RESPONSE;
	return result;

}

int NameSvrClient::query_is_dir_exist(const char * dir_path, int32_t & exist_flag) {
	SocketConnPtr cp;
        int ret = _pool.get(cp);
        if (ret < 0) {
                LOG4CXX_ERROR(_logger, __FUNCTION__ << ", could not get connection from pool");
                return NS_ERR_CLIENT_TO_SVR_NETWORK_ERR;
        }
        string request = ns_build_request_query_is_dir_exist(dir_path);
        string response;
        ret = send_and_recv_cmd(cp, _send_timeout, _recv_timeout, request.c_str(), request.size(), _max_response_size, response);
        if (ret < 0) {
                LOG4CXX_ERROR(_logger, __FUNCTION__ << ", send and recv cmd error, ret:" << ret);
                return NS_ERR_CLIENT_TO_SVR_NETWORK_ERR;
        }
	int result;
	ret = ns_parse_response_query_is_dir_exist(response.c_str(), result, exist_flag);
	if (ret < 0) return NS_ERR_INVALID_RESPONSE;
	return result;

}

int NameSvrClient::read_dir(const char * dir_path, list<string> & entries) {
	SocketConnPtr cp;
        int ret = _pool.get(cp);
        if (ret < 0) {
                LOG4CXX_ERROR(_logger, __FUNCTION__ << ", could not get connection from pool");
                return NS_ERR_CLIENT_TO_SVR_NETWORK_ERR;
        }
        string request = ns_build_request_read_dir(dir_path);
        string response;
        ret = send_and_recv_cmd(cp, _send_timeout, _recv_timeout, request.c_str(), request.size(), _max_response_size, response);
        if (ret < 0) {
                LOG4CXX_ERROR(_logger, __FUNCTION__ << ", send and recv cmd error, ret:" << ret);
                return NS_ERR_CLIENT_TO_SVR_NETWORK_ERR;
        }
	int result;
	ret = ns_parse_response_read_dir(response.c_str(), result, entries);
	if (ret < 0) return NS_ERR_INVALID_RESPONSE;
	LOG4CXX_INFO(_logger, __FUNCTION__ << ", ok, response:" << response);
	return result;
}
